package com.pronosticnews.client.admin.activity;

import java.util.LinkedList;
import java.util.Queue;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.activity.shared.Activity;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.AcceptsOneWidget;

public abstract class ActivityProxy extends AbstractActivity {

    private Activity impl;
    private Queue<Command> queue;
    private boolean asyncCalled;

    protected ActivityProxy(boolean eager) {
        this.queue = new LinkedList<Command>();
        if (eager) {
            ensureActivity();
        }
    }

    @Override
    public final String mayStop() {
        return this.impl == null ? null : this.impl.mayStop();
    }

    protected final void onAsyncFailure(Throwable reason) {
        // TODO
    }

    @Override
	public void onCancel() {
		queue(new Command() {
			public void execute() {
				ActivityProxy.this.impl.onCancel();
			}
		});
	}

	@Override
	public void onStop() {
		 queue(new Command() {
           public void execute() {
               ActivityProxy.this.impl.onStop();
           }
       });
	}

	@Override
	public void start(final AcceptsOneWidget display, final EventBus eventBus) {
		queue(new Command() {
			public void execute() {
				ActivityProxy.this.impl.start(display, eventBus);
			}
		});
	}

	protected final void onAsyncSuccess(Activity impl) {
        this.impl = impl;

        while (!this.queue.isEmpty()) {
            this.queue.poll().execute();
        }
    }

    protected abstract void runAsync();

    void ensureActivity() {
        if (!this.asyncCalled) {
            this.asyncCalled = true;
            runAsync();
        }
    }

    void queue(Command cmd) {
        ensureActivity();
        if (this.impl != null) {
            cmd.execute();
        } else {
            this.queue.add(cmd);
        }
    }

}
